package cn.imokay.juc.locksupport;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

public class LockSupportDemo1 {
    public static void main(String[] args) {

        //demo2();

        //demo3();

        demo4();
    }

    private static void demo4() {

        ArrayList<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            Thread thread = new Thread(() -> {
                LockSupport.park();
            }, "t" + i);
            threads.add(thread);
            thread.start();

        }

        try { TimeUnit.SECONDS.sleep(5); } catch (Exception e) { e.printStackTrace();}
        while (threads.size() == 1000) {
            for (Thread thread : threads) {
                LockSupport.unpark(thread);
            }
            break;
        }

    }

    private static void demo3() {
        //LockSupport,无需锁块，并且可以先发通行证
        //许可证unpark不可累计，只有一个
        Thread t1 = new Thread(() -> {
            //try { TimeUnit.SECONDS.sleep(2); } catch (Exception e) { e.printStackTrace();}
            System.out.println("t1 come in");
            LockSupport.park();
            System.out.println("t1 被唤醒");
        }, "t1");
        t1.start();

        new Thread(()->{
            System.out.println("t2 come in");
            try { TimeUnit.SECONDS.sleep(2); } catch (Exception e) { e.printStackTrace();}
            System.out.println("t2 唤醒 t1");
            LockSupport.unpark(t1);

        },"t2").start();
    }

    private static void demo1() {
        //当没有synchronized时，使用Object的wait和notif会报错
        //并且先notif，会无效
        Object o = new Object();
        new Thread(()->{
               synchronized (o){
                   System.out.println(Thread.currentThread().getName() + "\t--- come in");
                   try {
                       o.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }

                   System.out.println("t1被t2唤醒");
               }
        },"t1").start();

        try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace();}
        new Thread(()->{
                 synchronized (o){
                     System.out.println(Thread.currentThread().getName() + "\t--- come in");
                     System.out.println("t2唤醒t1");
                     o.notify();
                 }
        },"t2").start();
    }

    private static void demo2() {
        //当没有lock时，使用await的wait和signal会报错
        //并且先signal，会无效
        Object o = new Object();
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(()->{
            System.out.println(Thread.currentThread().getName() + "\t--- come in");
            lock.lock();
            try {
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }

            System.out.println("t1被t2唤醒");
        },"t1").start();

        try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace();}
        new Thread(()->{
            lock.lock();
            System.out.println(Thread.currentThread().getName() + "\t--- come in");
            System.out.println("t2唤醒t1");
            condition.signal();
            lock.unlock();
        },"t2").start();
    }
}
